package py.com.alfa.escriba.web.services.impl;

import java.util.HashMap;
import java.util.List;

import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import py.com.alfa.escriba.exception.ErrorCode;
import py.com.alfa.escriba.exception.ServiceException;
import py.com.alfa.escriba.persistence.dao.ReferenciaDAO;
import py.com.alfa.escriba.persistence.dto.referencia.BarrioDTO;
import py.com.alfa.escriba.persistence.dto.referencia.DepartamentoDTO;
import py.com.alfa.escriba.persistence.dto.referencia.DistritoDTO;
import py.com.alfa.escriba.persistence.dto.referencia.EmpleoDTO;
import py.com.alfa.escriba.persistence.dto.referencia.LocalidadDTO;
import py.com.alfa.escriba.persistence.dto.referencia.TabRefDTO;
import py.com.alfa.escriba.web.rest.dto.EmpleoResponseDTO;
import py.com.alfa.escriba.web.rest.dto.EmpleoTreeDTO;
import py.com.alfa.escriba.web.services.ReferenciaService;

@Transactional(readOnly = true)
public class ReferenciaServiceImpl implements ReferenciaService {

	private ReferenciaDAO refeDAO;
	
	public ReferenciaServiceImpl() {}

	public ReferenciaDAO getRefeDAO() {
		return refeDAO;
	}

	public void setRefeDAO(ReferenciaDAO refeDAO) {
		this.refeDAO = refeDAO;
	}

	@Override
	@Transactional(readOnly = false, propagation = Propagation.SUPPORTS, rollbackFor=ServiceException.class)
	public EmpleoResponseDTO obtenerEmpleos() throws ServiceException {
		HashMap<Long, EmpleoTreeDTO> lista = new HashMap<Long, EmpleoTreeDTO>();
		EmpleoResponseDTO res = new EmpleoResponseDTO();
		List<EmpleoDTO> emps = null;
		
//		emps = this.getRefeDAO().getEmpleos();
//		if ( emps == null || emps.isEmpty()) {
//			return res;
//		}
//		for (EmpleoDTO dto : emps) {
//			EmpleoTreeDTO em = this.empleoConvertTree(dto);
//			if ( em.getIdPadre() != null ) {
//				EmpleoTreeDTO padre = lista.get(dto.getIdPadre());
//				if ( padre == null) {
//				  throw new ServiceException(ErrorCode.NO_DATA_FOUND,"referencia.empleo.padre.error", em.getIdPadre(), em.getId());
//				}
//				padre.getHijos().add(em);
//			} else {
//				res.getHijos().add(em);
//			}
//			lista.put(em.getId(), em);
//		}
		
		return res;
	}
	
	
	private EmpleoTreeDTO empleoConvertTree(EmpleoDTO dto) {
		EmpleoTreeDTO res = new EmpleoTreeDTO();
		
		res.setId(dto.getId());
		res.setIdPadre(dto.getIdPadre());
		res.setDescripcion(dto.getDescripcion());
		
		return res;
	}


	@Override
	@Transactional(readOnly = false, propagation = Propagation.REQUIRED, rollbackFor=ServiceException.class)
	public EmpleoDTO crearEmpleo(EmpleoDTO dto) throws ServiceException {
		if ( dto == null) {
		   throw new ServiceException(ErrorCode.PARAMETER_ERROR,"referencia.empleo.not.info.error");
		}
		if ( dto.getDescripcion() == null ) {
		  throw new ServiceException(ErrorCode.PARAMETER_ERROR,"referencia.empleo.not.descripcion.error");
		}
		
		//this.getRefeDAO().insEmpleos(dto);
		
		return dto;
	}


	@Override
	@Transactional(readOnly = false, propagation = Propagation.SUPPORTS, rollbackFor=ServiceException.class)
	public void moverEmpleo(Long id, Long idDestino) throws ServiceException {
		if ( id == null || idDestino == null ) {
		   throw new ServiceException(ErrorCode.PARAMETER_ERROR,"referencia.empleo.not.mover.error");
		}
		//EmpleoDTO dto = this.getRefeDAO().getEmpleosById(id);
//		if ( dto == null ) {
//			throw new ServiceException(ErrorCode.PARAMETER_ERROR,"referencia.empleo.not.exist.error", id);
//		}
		//dto.setIdPadre(idDestino);
	    //this.getRefeDAO().updEmpleos(dto);
	}


	@Override
	@Transactional(readOnly = false, propagation = Propagation.SUPPORTS, rollbackFor=ServiceException.class)
	public EmpleoDTO actualizarEmpleo(EmpleoDTO dto) throws ServiceException {
		if ( dto == null) {
		  throw new ServiceException(ErrorCode.PARAMETER_ERROR,"referencia.empleo.not.info.error");
		}
		if ( dto.getDescripcion() == null ) {
		   throw new ServiceException(ErrorCode.PARAMETER_ERROR,"referencia.empleo.not.descripcion.error");
		}
		
//		int cant = this.getRefeDAO().updEmpleos(dto);
//		if ( cant == 0 ) {
//		  throw new ServiceException(ErrorCode.PARAMETER_ERROR,"referencia.empleo.not.exist.error", dto.getId());
//		}
		return dto;
	}

	@Override
	@Transactional(readOnly = false, propagation = Propagation.SUPPORTS, rollbackFor=ServiceException.class)
	public void eliminarEmpleo(Long id) throws ServiceException {
		if ( id == null ) {
		  throw new ServiceException(ErrorCode.PARAMETER_ERROR,"referencia.empleo.id.not.info.error");
		}
//		this.getRefeDAO().delHijosEmpleo(id);
//		int cant = this.getRefeDAO().delEmpleo(id);
//		if ( cant == 0 ) {
//		  throw new ServiceException(ErrorCode.PARAMETER_ERROR,"referencia.empleo.not.exist.error", id);
//		}	
	}

	@Override
	@Transactional(readOnly = false, propagation = Propagation.SUPPORTS, rollbackFor=ServiceException.class)
	public List<DepartamentoDTO> obtenerDepartamentos() throws ServiceException {
		List<DepartamentoDTO> res = null;		
	    res = this.getRefeDAO().getDepartamentos();
		return res;
	}

	@Override
	@Transactional(readOnly = false, propagation = Propagation.SUPPORTS, rollbackFor=ServiceException.class)
	public DepartamentoDTO crearDepartamento(DepartamentoDTO dto) throws ServiceException {
		if ( dto == null) {
		  throw new ServiceException(ErrorCode.PARAMETER_ERROR,"referencia.departamento.not.info.error");
		}
		if ( dto.getId() == null ) {
			  throw new ServiceException(ErrorCode.PARAMETER_ERROR,"referencia.departamento.not.id.error");
		}
		if ( dto.getNombre() == null ) {
		  throw new ServiceException(ErrorCode.PARAMETER_ERROR,"referencia.departamento.not.descripcion.error");
		}
			
		this.getRefeDAO().insDepartamentos(dto);			

		return dto;
	}

	@Override
	@Transactional(readOnly = false, propagation = Propagation.SUPPORTS, rollbackFor=ServiceException.class)
	public DepartamentoDTO actualizarDepartamento(DepartamentoDTO dto) throws ServiceException {
		if ( dto == null) {
			throw new ServiceException(ErrorCode.PARAMETER_ERROR,"referencia.departamento.not.info.error");
		}
		if ( dto.getNombre() == null ) {
			throw new ServiceException(ErrorCode.PARAMETER_ERROR,"referencia.departamento.not.descripcion.error");
		}
			
		int cant = this.getRefeDAO().updDepartamentos(dto);
		if ( cant == 0 ) {
			throw new ServiceException(ErrorCode.PARAMETER_ERROR,"referencia.departamento.not.exist.error", dto.getId());
		}
		return dto;
	}

	@Override
	@Transactional(readOnly = false, propagation = Propagation.SUPPORTS, rollbackFor=ServiceException.class)
	public void eliminarDepartamento(String id) throws ServiceException {
		if ( id == null ) {
			  throw new ServiceException(ErrorCode.PARAMETER_ERROR,"referencia.departamento.id.not.info.error");
		}
		//this.getRefeDAO().delBarriosByDepartamento(id);
		this.getRefeDAO().delDistritosByDepartamento(id);
		int cant = this.getRefeDAO().delDepartamentos(id);
		if ( cant == 0 ) {
			throw new ServiceException(ErrorCode.PARAMETER_ERROR,"referencia.departamento.not.exist.error", id);
		}	
	}

	@Override
	@Transactional(readOnly = false, propagation = Propagation.SUPPORTS, rollbackFor=ServiceException.class)
	public List<DistritoDTO> obtenerDistritos(String idDepartamento) throws ServiceException {
		List<DistritoDTO> res = null;
		if (idDepartamento == null ) {
			throw new ServiceException(ErrorCode.PARAMETER_ERROR,"referencia.distrito.not.departamento.error");
		}		
	    res = this.getRefeDAO().getDistritosByDepartamento(Long.valueOf(idDepartamento));
		return res;
	}

	@Override
	@Transactional(readOnly = false, propagation = Propagation.SUPPORTS, rollbackFor=ServiceException.class)
	public DistritoDTO crearDistritos(DistritoDTO dto) throws ServiceException {
		if ( dto == null) {
		  throw new ServiceException(ErrorCode.PARAMETER_ERROR,"referencia.distrito.not.info.error");
		}
		if ( dto.getIdDepartamento() == null ) {
			  throw new ServiceException(ErrorCode.PARAMETER_ERROR,"referencia.distrito.not.departamento.error");
		}
		if ( dto.getNombre() == null ) {
		  throw new ServiceException(ErrorCode.PARAMETER_ERROR,"referencia.distrito.not.descripcion.error");
		}
			
		this.getRefeDAO().insDistritos(dto);		

		return dto;
	}

	@Override
	@Transactional(readOnly = false, propagation = Propagation.SUPPORTS, rollbackFor=ServiceException.class)
	public DistritoDTO actualizarDistritos(DistritoDTO dto) throws ServiceException {
		if ( dto == null) {
			throw new ServiceException(ErrorCode.PARAMETER_ERROR,"referencia.distrito.not.info.error");
		}
		if ( dto.getNombre() == null ) {
			throw new ServiceException(ErrorCode.PARAMETER_ERROR,"referencia.distrito.not.descripcion.error");
		}
			
		int cant = this.getRefeDAO().updDistritos(dto);
		if ( cant == 0 ) {
			throw new ServiceException(ErrorCode.PARAMETER_ERROR,"referencia.distrito.not.exist.error", dto.getId());
		}
		return dto;
	}

	@Override
	@Transactional(readOnly = false, propagation = Propagation.SUPPORTS, rollbackFor=ServiceException.class)
	public void eliminarDistritos(Long id) throws ServiceException {
		if ( id == null ) {
			  throw new ServiceException(ErrorCode.PARAMETER_ERROR,"referencia.distrito.id.not.info.error");
		}
		//this.getRefeDAO().delBarriosByDistritos(id);
		int cant = this.getRefeDAO().delDistritos(id);
		if ( cant == 0 ) {
			throw new ServiceException(ErrorCode.PARAMETER_ERROR,"referencia.distrito.not.exist.error", id);
		}	
	}

	@Override
	@Transactional(readOnly = false, propagation = Propagation.SUPPORTS, rollbackFor=ServiceException.class)
	public List<BarrioDTO> obtenerBarrios(Long idDistrito) throws ServiceException {
		List<BarrioDTO> res = null;
		if (idDistrito == null ) {
			throw new ServiceException(ErrorCode.PARAMETER_ERROR,"referencia.barrio.not.distrito.error");
		}			
	    //res = this.getRefeDAO().getBarriosByDistritos(idDistrito);
		return res;
	}

	@Override
	@Transactional(readOnly = false, propagation = Propagation.SUPPORTS, rollbackFor=ServiceException.class)
	public BarrioDTO crearBarrios(BarrioDTO dto) throws ServiceException {
		if ( dto == null) {
		  throw new ServiceException(ErrorCode.PARAMETER_ERROR,"referencia.barrio.not.info.error");
		}
		if ( dto.getIdDepartamento() == null ) {
			  throw new ServiceException(ErrorCode.PARAMETER_ERROR,"referencia.barrio.not.departamento.error");
		}
		if ( dto.getIdDistrito() == null ) {
			  throw new ServiceException(ErrorCode.PARAMETER_ERROR,"referencia.barrio.not.distrito.error");
		}		
		if ( dto.getDescripcion() == null ) {
		  throw new ServiceException(ErrorCode.PARAMETER_ERROR,"referencia.barrio.not.descripcion.error");
		}
			
		//this.getRefeDAO().insBarrios(dto);		

		return dto;
	}

	@Override
	@Transactional(readOnly = false, propagation = Propagation.SUPPORTS, rollbackFor=ServiceException.class)
	public BarrioDTO actualizarBarrios(BarrioDTO dto) throws ServiceException {
		if ( dto == null) {
			throw new ServiceException(ErrorCode.PARAMETER_ERROR,"referencia.barrio.not.info.error");
		}
		if ( dto.getDescripcion() == null ) {
			throw new ServiceException(ErrorCode.PARAMETER_ERROR,"referencia.barrio.not.descripcion.error");
		}
			
//		int cant = this.getRefeDAO().updBarrios(dto);
//		if ( cant == 0 ) {
//			throw new ServiceException(ErrorCode.PARAMETER_ERROR,"referencia.barrio.not.exist.error", dto.getId());
//		}
		return dto;
	}

	@Override
	@Transactional(readOnly = false, propagation = Propagation.SUPPORTS, rollbackFor=ServiceException.class)
	public void eliminarBarrios(Long id) throws ServiceException {
		if ( id == null ) {
			  throw new ServiceException(ErrorCode.PARAMETER_ERROR,"referencia.barrio.id.not.info.error");
		}
//		int cant = this.getRefeDAO().delBarrios(id);
//		if ( cant == 0 ) {
//			throw new ServiceException(ErrorCode.PARAMETER_ERROR,"referencia.barrio.not.exist.error", id);
//		}	
	}

	@Override
	@Transactional(readOnly = false, propagation = Propagation.SUPPORTS, rollbackFor=ServiceException.class)
	public LocalidadDTO obtenerLocalidad(String idDepartamento) throws ServiceException {
		LocalidadDTO res = null;
		if (idDepartamento == null ) {
			throw new ServiceException(ErrorCode.PARAMETER_ERROR,"referencia.departamento.not.id.error");
		}			
	    //res = this.getRefeDAO().getLocalidadByDepartamento(idDepartamento);
		return res;
	}

	@Override
	@Transactional(readOnly = false, propagation = Propagation.SUPPORTS, rollbackFor=ServiceException.class)
	public DepartamentoDTO obtenerDepartamento(String id) throws ServiceException {
		if ( id == null ) {
			  throw new ServiceException(ErrorCode.PARAMETER_ERROR,"referencia.departamento.not.id.error");
		}
		DepartamentoDTO res = null;		
	    res = this.getRefeDAO().getDepartamentoById(Long.valueOf(id));
		return res;
	}

	@Override
	@Transactional(readOnly = false, propagation = Propagation.SUPPORTS, rollbackFor=ServiceException.class)
	public DistritoDTO obtenerDistrito(Long id) throws ServiceException {
		if ( id == null ) {
			  throw new ServiceException(ErrorCode.PARAMETER_ERROR,"referencia.distrito.not.id.error");
		}
		DistritoDTO res = null;		
	    res = this.getRefeDAO().getDistritoById(id);
		return res;
	}

	@Override
	@Transactional(readOnly = false, propagation = Propagation.SUPPORTS, rollbackFor=ServiceException.class)
	public List<TabRefDTO> obtenerTablaReferencia(String tabla) throws ServiceException {
		if ( tabla == null ) {
			  throw new ServiceException(ErrorCode.PARAMETER_ERROR,"referencia.tabref.not.tname.error");
		}
		List<TabRefDTO> res = null;		
	    res = this.getRefeDAO().getTablaRefByTabla(tabla);
		return res;
	}

	
}
